/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DigimonAdventure.MP3Player;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 *
 * @author Kris Derril Siregar
 */
public final class MusicPlayer implements Runnable {
    private class Player{
        private AudioInputStream in;
        private AudioFormat baseFormat;
        private AudioFormat decodedFormat;
        private AudioInputStream decodedIn;
        private SourceDataLine line;
        public Player(String location){
            try {
                in = AudioSystem.getAudioInputStream(getClass().getResource(location));
                baseFormat = in.getFormat();
                decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
                decodedIn = AudioSystem.getAudioInputStream(decodedFormat, in);
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);
                line = (SourceDataLine) AudioSystem.getLine(info);
                stopped =false;
            } catch (UnsupportedAudioFileException ex) {
                System.err.println("File format not supported");
            } catch (IOException ex) {
                System.err.println("IO exception");
            } catch (LineUnavailableException ex) {

            }
        }
        public void stop(){
            try {
                in.close();
                decodedIn.close();
                line.flush();
                line.stop();
                line.close();
            } catch (IOException ex) {
                
            }
        }

        private void play() {
            try {
                line.open(decodedFormat);
                if (line != null) {
                    byte[] data = new byte[4096]; // 4k is a reasonable transfer size.
                    // Start
                    line.start(); // Start the line.
                    int nBytesRead;
                    while ((nBytesRead = decodedIn.read(data, 0, data.length)) != -1) {
                        line.write(data, 0, nBytesRead);
                    }
                    // Stop
                    line.drain();
                    line.stop();
                    line.close();
                    decodedIn.close();
                }
            } catch (IOException ex) {
            } catch (LineUnavailableException ex) {
            }
        }
    }


    private String location;
    private boolean stopped;
    private volatile Player player;

    public MusicPlayer (String location){
        this.location = location;
        stopped = false;
    }
    private void playMusicAndRepeat(){
        stopped = Boolean.FALSE;
        while(!stopped){
            player = new Player(location);
            player.play();
        }
    }
    public void stopMusic(){
        stopped = true;
        player.stop();
    }
    public void pauseMusic(){
        throw new UnsupportedOperationException("Yayaya. Not supported yet");
    }
    public void run() {
        this.playMusicAndRepeat();
    }
    public static void main (String [] args) throws InterruptedException{
        final MusicPlayer a = new MusicPlayer("/DigimonAdventure/Sound/City.mp3");
        new Thread (new Runnable() {
            public void run() {
                a.playMusicAndRepeat();
            }
        }).start();
        for(int i = 0; i < 5;i++){
            Thread.sleep(1000);
        }
        a.stopMusic();
    }
}
